
#include "./../inc/main.h"

// 将、帅的实现
KingPiece::KingPiece(PieceColor c, int x, int y) : ChessPiece(King, c, x, y)
{
}

bool KingPiece::canMoveTo(const Point &target, const vector<vector<ChessPiece *>> &board) const
{
    int currentX = getPosition().x(); // 当前x（列）
    int currentY = getPosition().y(); // 当前y（行）
    int targetX = target.x();         // 目标x（列）
    int targetY = target.y();         // 目标y（行）

    // 检查目标位置是否有己方棋子
    if (board[targetX][targetY] != nullptr &&
        board[targetX][targetY]->getPieceColor() == getPieceColor())
    {
        return false; // 不能吃己方棋子
    }

    // 检查九宫格范围
    if (getPieceColor() == Red)
    {
        // 红方帅：列x∈[3,5]，行y∈[0,2]
        if (targetX < 3 || targetX > 5 || targetY < 0 || targetY > 2)
        {
            return false;
        }
    }
    else
    {
        // 黑方将：列x∈[3,5]，行y∈[7,9]
        if (targetX < 3 || targetX > 5 || targetY < 7 || targetY > 9)
        {
            return false;
        }
    }

    // 检查移动步长
    int dx = abs(targetX - currentX);
    int dy = abs(targetY - currentY);
    return (dx + dy == 1); // 横向或纵向一步
}

// 士的实现
AdvisorPiece::AdvisorPiece(PieceColor c, int x, int y) : ChessPiece(Advisor, c, x, y)
{
}

bool AdvisorPiece::canMoveTo(const Point &target, const vector<vector<ChessPiece *>> &board) const
{
    int currentX = getPosition().x();
    int currentY = getPosition().y();
    int targetX = target.x();
    int targetY = target.y();

    // 检查目标位置是否有己方棋子
    if (board[targetX][targetY] != nullptr &&
        board[targetX][targetY]->getPieceColor() == getPieceColor())
    {
        return false;
    }

    // 检查九宫格范围
    if (getPieceColor() == Red)
    {
        if (targetX < 3 || targetX > 5 || targetY < 0 || targetY > 2)
        {
            return false;
        }
    }
    else
    {
        if (targetX < 3 || targetX > 5 || targetY < 7 || targetY > 9)
        {
            return false;
        }
    }

    // 检查移动步长
    int dx = abs(targetX - currentX);
    int dy = abs(targetY - currentY);
    return (dx == 1 && dy == 1); // 对角线一步
}
// 象的实现
ElephantPiece::ElephantPiece(PieceColor c, int x, int y) : ChessPiece(Elephant, c, x, y)
{
}

bool ElephantPiece::canMoveTo(const Point &target, const vector<vector<ChessPiece *>> &board) const
{
    int dx = target.x() - getPosition().x();
    int dy = target.y() - getPosition().y();

    // 由于棋盘旋转90度，象不能过河的判断需要改变
    if (getPieceColor() == Red &&
        ((getPosition().y() <= 4 && target.y() >= 5) || // 红方从左到右过河
         (getPosition().y() >= 5 && target.y() <= 4)))  // 红方从右到左过河
        return false;

    if (getPieceColor() == Black &&
        ((getPosition().y() <= 4 && target.y() >= 5) || // 黑方从左到右过河
         (getPosition().y() >= 5 && target.y() <= 4)))  // 黑方从右到左过河
        return false;

    if (abs(dx) == 2 && abs(dy) == 2)
    {
        int eyeX = (getPosition().x() + target.x()) / 2;
        int eyeY = (getPosition().y() + target.y()) / 2;
        return board[eyeX][eyeY] == nullptr;
    }
    return false;
}

// 马的实现
HorsePiece::HorsePiece(PieceColor c, int x, int y) : ChessPiece(Horse, c, x, y)
{
}

bool HorsePiece::canMoveTo(const Point &target, const vector<vector<ChessPiece *>> &board) const
{
    int dx = target.x() - getPosition().x();
    int dy = target.y() - getPosition().y();

    // 马走日
    if ((abs(dx) == 1 && abs(dy) == 2) || (abs(dx) == 2 && abs(dy) == 1))
    {
        // 计算马脚位置
        int legX, legY;
        if (abs(dx) == 2)
        {
            legX = getPosition().x() + dx / 2;
            legY = getPosition().y();
        }
        else
        {
            legX = getPosition().x();
            legY = getPosition().y() + dy / 2;
        }

        if (legX < 0 || legX >= static_cast<int>(board.size()) ||  // x范围（列数）
            legY < 0 || legY >= static_cast<int>(board[0].size())) // y范围（行数）
            return false;

        return board[legX][legY] == nullptr;
    }
    return false;
}

// 车的实现
ChariotPiece::ChariotPiece(PieceColor c, int x, int y) : ChessPiece(Chariot, c, x, y)
{
}

bool ChariotPiece::canMoveTo(const Point &target, const vector<vector<ChessPiece *>> &board) const
{
    int startX = getPosition().x();
    int startY = getPosition().y();
    int endX = target.x();
    int endY = target.y();

    if (startX != endX && startY != endY)
        return false; // 必须直线移动

    if (startX == endX)
    {
        // 垂直移动
        int step = (endY > startY) ? 1 : -1;
        for (int y = startY + step; y != endY; y += step)
        {
            // 检查 board[startX][y]
            if (board[startX][y] != nullptr)
                return false;
        }
    }
    else
    {
        // 水平移动
        int step = (endX > startX) ? 1 : -1;
        for (int x = startX + step; x != endX; x += step)
        {
            // 检查 board[x][startY]
            if (board[x][startY] != nullptr)
                return false;
        }
    }
    return true;
}

// 炮的实现
CannonPiece::CannonPiece(PieceColor c, int x, int y) : ChessPiece(Cannon, c, x, y) {}

bool CannonPiece::canMoveTo(const Point &target, const vector<vector<ChessPiece *>> &board) const
{
    int startX = getPosition().x();
    int startY = getPosition().y();
    int endX = target.x();
    int endY = target.y();

    // 必须直线移动
    if (startX != endX && startY != endY)
        return false;

    // 计算路径上的棋子数量
    int pieceCount = 0;
    if (startX == endX)
    {
        // 垂直移动
        int step = (endY > startY) ? 1 : -1;
        for (int y = startY + step; y != endY; y += step)
        {
            if (board[startX][y] != nullptr)
                pieceCount++;
        }
    }
    else if (startY == endY)
    {
        // 水平移动
        int step = (endX > startX) ? 1 : -1;
        for (int x = startX + step; x != endX; x += step)
        {
            if (board[x][startY] != nullptr)
                pieceCount++;
        }
    }
    else
    {
        return false;
    }

    // 检查目标位置
    if (board[endX][endY] != nullptr)
    {
        // 如果目标位置有棋子，必须跨越一个棋子才能吃
        return pieceCount == 1;
    }
    else
    {
        // 如果目标位置无棋子，则路径不能有棋子
        return pieceCount == 0;
    }
}

// 兵/卒的实现
PawnPiece::PawnPiece(PieceColor c, int x, int y) : ChessPiece(Pawn, c, x, y) {}

// 兵/卒的实现
bool PawnPiece::canMoveTo(const Point &target, const vector<vector<ChessPiece *>> &board) const
{
    int currentX = getPosition().x(); // 棋盘x坐标（垂直方向）
    int currentY = getPosition().y(); // 棋盘y坐标（屏幕左右）
    int targetX = target.x();
    int targetY = target.y();

    int dx = targetX - currentX; // 垂直方向变化（x轴,屏幕上下）
    int dy = targetY - currentY; // 水平方向变化（y轴,屏幕左右）

    // 检查目标位置是否有己方棋子
    if (board[targetX][targetY] != nullptr &&
        board[targetX][targetY]->getPieceColor() == getPieceColor())
    {
        return false;
    }

    if (getPieceColor() == Red) // 红方兵
    {
        // 未过河：只能向屏幕右边
        if (currentY <= 4)
        {
            return (dy == 1 && dx == 0);
        }
        else // 已过河可向右或垂直上下移动
        {
            return (dy == 1 && dx == 0) ||
                   (dx == 1 && dy == 0) ||
                   (dx == -1 && dy == 0);
        }
    }
    else // 黑方兵
    {
        // 未过河，只能向屏幕左边
        if (currentY >= 5)
        {
            return (dy == -1 && dx == 0);
        }
        else // 已过河（y<5）：可向左或垂直上下移动
        {
            return (dy == -1 && dx == 0) ||
                   (dx == 1 && dy == 0) ||
                   (dx == -1 && dy == 0);
        }
    }
}

// 工厂类实现
ChessPiece *ChessPieceFactory::createPiece(PieceType type, PieceColor color, int x, int y)
{
    switch (type)
    {
    case King:
        return new KingPiece(color, x, y);
    case Advisor:
        return new AdvisorPiece(color, x, y);
    case Elephant:
        return new ElephantPiece(color, x, y);
    case Horse:
        return new HorsePiece(color, x, y);
    case Chariot:
        return new ChariotPiece(color, x, y);
    case Cannon:
        return new CannonPiece(color, x, y);
    case Pawn:
        return new PawnPiece(color, x, y);
    default:
        return 0;
    }
}